{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pandas DataFrame Parser\n",
    "\n",
    "A Pandas DataFrame is a popular data structure in the Python programming language, commonly used for data manipulation and analysis. It provides a comprehensive set of tools for working with structured data, making it a versatile option for tasks such as data cleaning, transformation, and analysis.\n",
    "\n",
    "This output parser allows users to specify an arbitrary Pandas DataFrame and query LLMs for data in the form of a formatted dictionary that extracts data from the corresponding DataFrame. Keep in mind that large language models are leaky abstractions! You'll have to use an LLM with sufficient capacity to generate a well-formed query as per the defined format instructions.\n",
    "\n",
    "Use Pandas' DataFrame object to declare the DataFrame you wish to perform queries on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pprint\n",
    "from typing import Any, Dict\n",
    "\n",
    "import pandas as pd\n",
    "from langchain.output_parsers import PandasDataFrameOutputParser\n",
    "from langchain.prompts import PromptTemplate\n",
    "from langchain_openai import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = ChatOpenAI(temperature=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Solely for documentation purposes.\n",
    "def format_parser_output(parser_output: Dict[str, Any]) -> None:\n",
    "    for key in parser_output.keys():\n",
    "        parser_output[key] = parser_output[key].to_dict()\n",
    "    return pprint.PrettyPrinter(width=4, compact=True).pprint(parser_output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define your desired Pandas DataFrame.\n",
    "df = pd.DataFrame(\n",
    "    {\n",
    "        \"num_legs\": [2, 4, 8, 0],\n",
    "        \"num_wings\": [2, 0, 0, 0],\n",
    "        \"num_specimen_seen\": [10, 2, 1, 8],\n",
    "    }\n",
    ")\n",
    "\n",
    "# Set up a parser + inject instructions into the prompt template.\n",
    "parser = PandasDataFrameOutputParser(dataframe=df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'num_wings': {0: 2,\n",
      "               1: 0,\n",
      "               2: 0,\n",
      "               3: 0}}\n"
     ]
    }
   ],
   "source": [
    "# Here's an example of a column operation being performed.\n",
    "df_query = \"Retrieve the num_wings column.\"\n",
    "\n",
    "# Set up the prompt.\n",
    "prompt = PromptTemplate(\n",
    "    template=\"Answer the user query.\\n{format_instructions}\\n{query}\\n\",\n",
    "    input_variables=[\"query\"],\n",
    "    partial_variables={\"format_instructions\": parser.get_format_instructions()},\n",
    ")\n",
    "\n",
    "chain = prompt | model | parser\n",
    "parser_output = chain.invoke({\"query\": df_query})\n",
    "\n",
    "format_parser_output(parser_output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'0': {'num_legs': 2,\n",
      "       'num_specimen_seen': 10,\n",
      "       'num_wings': 2}}\n"
     ]
    }
   ],
   "source": [
    "# Here's an example of a row operation being performed.\n",
    "df_query = \"Retrieve the first row.\"\n",
    "\n",
    "# Set up the prompt.\n",
    "prompt = PromptTemplate(\n",
    "    template=\"Answer the user query.\\n{format_instructions}\\n{query}\\n\",\n",
    "    input_variables=[\"query\"],\n",
    "    partial_variables={\"format_instructions\": parser.get_format_instructions()},\n",
    ")\n",
    "\n",
    "chain = prompt | model | parser\n",
    "parser_output = chain.invoke({\"query\": df_query})\n",
    "\n",
    "format_parser_output(parser_output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'mean': 4.0}\n"
     ]
    }
   ],
   "source": [
    "# Here's an example of a random Pandas DataFrame operation limiting the number of rows\n",
    "df_query = \"Retrieve the average of the num_legs column from rows 1 to 3.\"\n",
    "\n",
    "# Set up the prompt.\n",
    "prompt = PromptTemplate(\n",
    "    template=\"Answer the user query.\\n{format_instructions}\\n{query}\\n\",\n",
    "    input_variables=[\"query\"],\n",
    "    partial_variables={\"format_instructions\": parser.get_format_instructions()},\n",
    ")\n",
    "\n",
    "chain = prompt | model | parser\n",
    "parser_output = chain.invoke({\"query\": df_query})\n",
    "\n",
    "print(parser_output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "ename": "OutputParserException",
     "evalue": "Invalid column: num_fingers. Please check the format instructions.",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mOutputParserException\u001b[0m                     Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[23], line 12\u001b[0m\n\u001b[1;32m      5\u001b[0m prompt \u001b[38;5;241m=\u001b[39m PromptTemplate(\n\u001b[1;32m      6\u001b[0m     template\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAnswer the user query.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{format_instructions}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{query}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m      7\u001b[0m     input_variables\u001b[38;5;241m=\u001b[39m[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mquery\u001b[39m\u001b[38;5;124m\"\u001b[39m],\n\u001b[1;32m      8\u001b[0m     partial_variables\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mformat_instructions\u001b[39m\u001b[38;5;124m\"\u001b[39m: parser\u001b[38;5;241m.\u001b[39mget_format_instructions()},\n\u001b[1;32m      9\u001b[0m )\n\u001b[1;32m     11\u001b[0m chain \u001b[38;5;241m=\u001b[39m prompt \u001b[38;5;241m|\u001b[39m model \u001b[38;5;241m|\u001b[39m parser\n\u001b[0;32m---> 12\u001b[0m parser_output \u001b[38;5;241m=\u001b[39m \u001b[43mchain\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mquery\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mdf_query\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:1616\u001b[0m, in \u001b[0;36mRunnableSequence.invoke\u001b[0;34m(self, input, config)\u001b[0m\n\u001b[1;32m   1614\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m   1615\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m i, step \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msteps):\n\u001b[0;32m-> 1616\u001b[0m         \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mstep\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1617\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1618\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;66;43;03m# mark each step as a child run\u001b[39;49;00m\n\u001b[1;32m   1619\u001b[0m \u001b[43m            \u001b[49m\u001b[43mpatch_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1620\u001b[0m \u001b[43m                \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43mf\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mseq:step:\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mi\u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1621\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1622\u001b[0m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1623\u001b[0m \u001b[38;5;66;03m# finish the root run\u001b[39;00m\n\u001b[1;32m   1624\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/output_parsers/base.py:170\u001b[0m, in \u001b[0;36mBaseOutputParser.invoke\u001b[0;34m(self, input, config)\u001b[0m\n\u001b[1;32m    166\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minvoke\u001b[39m(\n\u001b[1;32m    167\u001b[0m     \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28minput\u001b[39m: Union[\u001b[38;5;28mstr\u001b[39m, BaseMessage], config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m    168\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m T:\n\u001b[1;32m    169\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(\u001b[38;5;28minput\u001b[39m, BaseMessage):\n\u001b[0;32m--> 170\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_with_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    171\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43;01mlambda\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43minner_input\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse_result\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    172\u001b[0m \u001b[43m                \u001b[49m\u001b[43m[\u001b[49m\u001b[43mChatGeneration\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minner_input\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m    173\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    174\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m    175\u001b[0m \u001b[43m            \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    176\u001b[0m \u001b[43m            \u001b[49m\u001b[43mrun_type\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mparser\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m    177\u001b[0m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    178\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    179\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_with_config(\n\u001b[1;32m    180\u001b[0m             \u001b[38;5;28;01mlambda\u001b[39;00m inner_input: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mparse_result([Generation(text\u001b[38;5;241m=\u001b[39minner_input)]),\n\u001b[1;32m    181\u001b[0m             \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m    182\u001b[0m             config,\n\u001b[1;32m    183\u001b[0m             run_type\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparser\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    184\u001b[0m         )\n",
      "File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/base.py:906\u001b[0m, in \u001b[0;36mRunnable._call_with_config\u001b[0;34m(self, func, input, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m    899\u001b[0m run_manager \u001b[38;5;241m=\u001b[39m callback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m    900\u001b[0m     dumpd(\u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m    901\u001b[0m     \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m    902\u001b[0m     run_type\u001b[38;5;241m=\u001b[39mrun_type,\n\u001b[1;32m    903\u001b[0m     name\u001b[38;5;241m=\u001b[39mconfig\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_name\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[1;32m    904\u001b[0m )\n\u001b[1;32m    905\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 906\u001b[0m     output \u001b[38;5;241m=\u001b[39m \u001b[43mcall_func_with_variable_args\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    907\u001b[0m \u001b[43m        \u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\n\u001b[1;32m    908\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    909\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m    910\u001b[0m     run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n",
      "File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/runnables/config.py:308\u001b[0m, in \u001b[0;36mcall_func_with_variable_args\u001b[0;34m(func, input, config, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m    306\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_manager \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m accepts_run_manager(func):\n\u001b[1;32m    307\u001b[0m     kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_manager\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m run_manager\n\u001b[0;32m--> 308\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/output_parsers/base.py:171\u001b[0m, in \u001b[0;36mBaseOutputParser.invoke.<locals>.<lambda>\u001b[0;34m(inner_input)\u001b[0m\n\u001b[1;32m    166\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minvoke\u001b[39m(\n\u001b[1;32m    167\u001b[0m     \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28minput\u001b[39m: Union[\u001b[38;5;28mstr\u001b[39m, BaseMessage], config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m    168\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m T:\n\u001b[1;32m    169\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(\u001b[38;5;28minput\u001b[39m, BaseMessage):\n\u001b[1;32m    170\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_with_config(\n\u001b[0;32m--> 171\u001b[0m             \u001b[38;5;28;01mlambda\u001b[39;00m inner_input: \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse_result\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    172\u001b[0m \u001b[43m                \u001b[49m\u001b[43m[\u001b[49m\u001b[43mChatGeneration\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minner_input\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m    173\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m    174\u001b[0m             \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m    175\u001b[0m             config,\n\u001b[1;32m    176\u001b[0m             run_type\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparser\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    177\u001b[0m         )\n\u001b[1;32m    178\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    179\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_with_config(\n\u001b[1;32m    180\u001b[0m             \u001b[38;5;28;01mlambda\u001b[39;00m inner_input: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mparse_result([Generation(text\u001b[38;5;241m=\u001b[39minner_input)]),\n\u001b[1;32m    181\u001b[0m             \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m    182\u001b[0m             config,\n\u001b[1;32m    183\u001b[0m             run_type\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparser\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    184\u001b[0m         )\n",
      "File \u001b[0;32m~/workplace/langchain/libs/core/langchain_core/output_parsers/base.py:222\u001b[0m, in \u001b[0;36mBaseOutputParser.parse_result\u001b[0;34m(self, result, partial)\u001b[0m\n\u001b[1;32m    209\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mparse_result\u001b[39m(\u001b[38;5;28mself\u001b[39m, result: List[Generation], \u001b[38;5;241m*\u001b[39m, partial: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m T:\n\u001b[1;32m    210\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Parse a list of candidate model Generations into a specific format.\u001b[39;00m\n\u001b[1;32m    211\u001b[0m \n\u001b[1;32m    212\u001b[0m \u001b[38;5;124;03m    The return value is parsed from only the first Generation in the result, which\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    220\u001b[0m \u001b[38;5;124;03m        Structured output.\u001b[39;00m\n\u001b[1;32m    221\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[0;32m--> 222\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtext\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/workplace/langchain/libs/langchain/langchain/output_parsers/pandas_dataframe.py:90\u001b[0m, in \u001b[0;36mPandasDataFrameOutputParser.parse\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m     88\u001b[0m request_type, request_params \u001b[38;5;241m=\u001b[39m splitted_request\n\u001b[1;32m     89\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m request_type \u001b[38;5;129;01min\u001b[39;00m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid column\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid operation\u001b[39m\u001b[38;5;124m\"\u001b[39m}:\n\u001b[0;32m---> 90\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m OutputParserException(\n\u001b[1;32m     91\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrequest\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m. Please check the format instructions.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     92\u001b[0m     )\n\u001b[1;32m     93\u001b[0m array_exists \u001b[38;5;241m=\u001b[39m re\u001b[38;5;241m.\u001b[39msearch(\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m(\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124m[.*?\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124m])\u001b[39m\u001b[38;5;124m\"\u001b[39m, request_params)\n\u001b[1;32m     94\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array_exists:\n",
      "\u001b[0;31mOutputParserException\u001b[0m: Invalid column: num_fingers. Please check the format instructions."
     ]
    }
   ],
   "source": [
    "# Here's an example of a poorly formatted query\n",
    "df_query = \"Retrieve the mean of the num_fingers column.\"\n",
    "\n",
    "# Set up the prompt.\n",
    "prompt = PromptTemplate(\n",
    "    template=\"Answer the user query.\\n{format_instructions}\\n{query}\\n\",\n",
    "    input_variables=[\"query\"],\n",
    "    partial_variables={\"format_instructions\": parser.get_format_instructions()},\n",
    ")\n",
    "\n",
    "chain = prompt | model | parser\n",
    "parser_output = chain.invoke({\"query\": df_query})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
